package com.litchi.tutor.service.impl;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.litchi.tutor.common.cons.RedisKey;
import com.litchi.tutor.common.entity.Region;
import com.litchi.tutor.common.util.RedisUtil;
import com.litchi.tutor.mapper.RegionMapper;
import com.litchi.tutor.service.RegionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author XuRuiPeng
 * @date 2021/10/28 9:20
 */
@Service
public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements RegionService {

    @Autowired
    RedisUtil redisUtil;

    @Override
    public Map<String, Object> getRegion(String code, String model) {
        Map<String, Object> region = new HashMap<>();
        // code非空 扁平化数据
        if (code != null && ("list".equals(model) || model == null)) {
            region = getRegionByList(code);
        }
        // code非空 树形结构数据
        if (code != null && "tree".equals(model)) {
//            region = getRegionByTree(code);
            region = getRegionByTree(code);
        }
        // 不传code 扁平化数据 查全国
        if (code == null && ("list".equals(model) || model == null)) {
            region = getAllRegionByList();
        }
        // 不传code 树形数据 查全国
        if (code == null &&  "tree".equals(model)) {
            region = getAllRegionByTree();
        }
        return region;
    }


    /**
     * 树形结构查全国
     * @return
     */
    public Map<String,Object> getAllRegionByTree() {
        Map<String, Object> mapData = new HashMap<>();
        String treeInfo = redisUtil.get(RedisKey.REGION_TREE);
        List<Region> regionList1 = JSONObject.parseArray(treeInfo, Region.class);
        if (regionList1 != null) {
            mapData.put("tree", regionList1);
        } else {
            List<Region> regionList = baseMapper.selectList(null);
            List<Region> list = new ArrayList<>();
            // 根据pcode排序分组
            Map<String, List<Region>> map = regionList.stream()
                    .sorted(Comparator.comparing(Region::getCode))
                    .sorted(Comparator.comparing(Region::getPcode))
                    .map(item -> {
                        Region region = new Region();
                        BeanUtils.copyProperties(item, region);
                        return region;
                    }).collect(Collectors.groupingBy(Region::getPcode, Collectors.toList()));

            // 整个排序
            TreeMap<String, List<Region>> sortedMap = MapUtil.sort(map);
            sortedMap.forEach((pcode, collect) -> {
                if ("0".equals(pcode)) {
                    list.addAll(collect);
                }
                collect.forEach(item -> item.setChildren(map.get(item.getCode())));
            });
            redisUtil.set(RedisKey.REGION_TREE, list);
            mapData.put("tree", list);
        }
            return mapData;
    }

    @Override
    public Map<String, List<Region>> test2() {
        Map<String, List<Region>> map = new HashMap<>();
        List<Region> regionList = list();
        List<Region> emptyList = new ArrayList<>();

        // 将数组数据转为map结构
        Map<String, List<Region>> regionMap = regionList.stream().map(item -> {
            Region region = new Region();
            BeanUtils.copyProperties(item, region);
            return region;
        }).collect(Collectors.groupingBy(Region::getPcode, Collectors.toList()));

        // 封装树形结构并塞进emptyList数组中
        regionMap.forEach((pcode, collect) -> {
            if (pcode.equals("0")) {
                emptyList.addAll(collect);
            }
            collect.forEach(item -> {
                item.setChildren(regionMap.get(item.getCode()));
            });
        });
        map.put("tree", emptyList);
        return map;
    }

    /**
     * 查全国数据 扁平化数据
     * @return
     */
    public Map<String, Object> getAllRegionByList() {
        Map<String, Object> map = new HashMap<>();
        List<Region> list = new ArrayList<>();

        String reidsRegionInfo = redisUtil.get(RedisKey.REGION_LIST);
        list = JSONObject.parseArray(reidsRegionInfo, Region.class);
        if (list != null) {
            map.put("list", list);
        } else {
            List regionList = baseMapper.selectList(null);
            map.put("list", regionList);
            redisUtil.set(RedisKey.REGION_LIST, regionList);
        }
        return map;
    }

    /**
     * 获取树形结构数据（递归）
     * @param code
     * @return
     */
    public Map<String, Object> getRegionByTree(String code) {
        Map<String, Object> map = new HashMap<>();
        // 获取list数据
        Map<String, Object> regionByList = getRegionByList(code);
        List<Region> list = (List<Region>) regionByList.get("list");
        Region region = list.get(0);
        List<Region> collect = list.stream().filter(item -> item.getPcode().equals(code))
                .map((item) -> {
                    item.setChildren(getChildren(item, list));
                    return item;
                }).collect(Collectors.toList());
        region.setChildren(collect);
        map.put("tree", region);
        return map;
    }

    /**
     * 获取子集
     * @param region
     * @param list
     * @return
     */
    public List<Region> getChildren(Region region, List<Region> list) {
        List<Region> collect = list.stream()
                .filter(item -> {
                    return Objects.equals(item.getPcode(), region.getCode());
                })
                .map((item) -> {
                    item.setChildren(getChildren(item, list));
                    return item;
                }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 获取扁平化数据
     * @param code
     * @return
     */
    public Map<String, Object> getRegionByList(String code) {
        HashMap<String, Object> map = new HashMap<>();
        Region region = getOne(new QueryWrapper<Region>().eq("code", code));
        String substring = code.substring(0, 6);
        // code 前两位
        String first = substring.substring(0, 2);
        // code 三四位
        String second = substring.substring(2, 4);
        // code 五六位
        String third = substring.substring(4, 6);

        List<Region> regionData = new ArrayList<>();
        // 不等于"00"说明这条数据就是这一级的
        if (!("00".equals(third))) {    // 走这里说明只有一条数据即本身，xxxxxx
            regionData.add(region);
        } else if (!("00".equals(second))) {    // 走这里说明xxxx00
            List<Region> regionList = baseMapper.selectList(new QueryWrapper<Region>().like("pcode", first + second + "%").or().eq("code", code));
            regionData.addAll(regionList);
        } else {    // 走这里说明xx0000
            List<Region> regionPage1 = baseMapper.selectList(new QueryWrapper<Region>().like("pcode", first + "%").or().eq("code", code));
            regionData.addAll(regionPage1);
        }
        map.put("list", regionData);
        return map;
    }
}
